package com.varian.auth.service.impl;

import com.varian.auth.service.IUserDetailService;
import com.varian.security.constant.SecurityConstant;
import com.varian.security.model.LoginUser;
import com.varian.security.model.LoginUserBuilder;
import com.varian.system.dto.UserDetailDTO;
import com.varian.system.remote.SysUserRemote;
import com.varian.tool.Func;
import com.varian.tool.result.R;
import lombok.RequiredArgsConstructor;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * @author ben
 * @since 2024/6/26
 */
@Service
@RequiredArgsConstructor
public class UserDetailServiceImpl implements IUserDetailService {

    private final SysUserRemote userRemote;
    private final MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        R<UserDetailDTO> result = userRemote.getUserByUsername(username);
        UserDetailDTO bo = Func.getRetOpt(result, () -> new UsernameNotFoundException(this.messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found")));
        return buildLoginUser(bo);
    }

    private void processExtraMap(LoginUserBuilder builder, UserDetailDTO dto) {
        builder.put(SecurityConstant.EXTRA_KEY_DEPT_ID, dto.getDeptId());
    }

    private LoginUser buildLoginUser(UserDetailDTO dto) {
        LoginUserBuilder builder = new LoginUserBuilder();
        builder.setUserId(dto.getId())
                .setUsername(dto.getUsername())
                .setPassword(dto.getPassword())
                .setNickname(dto.getNickname())
                .setAvatar(dto.getAvatar())
                .setUserStatus(dto.getUserStatus())
                .setAuthorities(dto.getPermissionCodes());
        processExtraMap(builder, dto);
        return builder.build();
    }
}
